#ifndef __WIZ_DATATYPE_FOREACH_HPP__SHANHAOBO_19800429__
#define __WIZ_DATATYPE_FOREACH_HPP__SHANHAOBO_19800429__

#include "../../Base/WizBase.hpp"

namespace Wiz
{
    //////////////////////////////////////////////////////////////////////////
    namespace ForEach
    {
        template<class ContainerT>
        struct Type
        {
            ////////////////////////////////////
            typedef typename ContainerT::tIterator    tIterator;
            ////////////////////////////////////
            ContainerT& m_Container;
            tIterator m_Next;
            tIterator& m_Curr;
            Type(tIterator& Curr, ContainerT& Container) : m_Curr(Curr), m_Container(Container), m_Next(Container.Begin())
            {
            }
            ::Wiz::Bool::Type HasMoreElement()
            {
                if (m_Next != m_Container.End())
                {
                    m_Curr = m_Next;
                    m_Next++;
                    return ::Wiz::Bool::True;
                }
                return ::Wiz::Bool::False;
            }

            ::Wiz::Void::Type Erase()
            {
                m_Next = m_Container.Erase(m_Curr);
            }
        };
    } /// end of namespace ForEach
    //////////////////////////////////////////////////////////////////////////

#define  WIZ_FOREACH_ITER(ItrT, Itr, Container) for(ItrT Itr(Container); Itr; ++Itr)
    namespace ForEachIter
    {
        template<class ContainerT>
        struct Type : public ::Wiz::UnspecifiedBool::Type<Type<ContainerT>, ::Wiz::Noncopyable::Type>
        {
            ////////////////////////////////////
            typedef typename ContainerT::tIterator          tIterator;
            typedef typename ContainerT::tIteratorConst     tIteratorConst;
            typedef typename ContainerT::tElement           tElement;
            typedef typename ContainerT::tElementConst      tElementConst;
            ////////////////////////////////////

            Type(ContainerT& Container) : m_Curr(Container.Begin()), m_End(Container.End())
            {
            }

            /// PreIncrement
            tIterator& operator++()
            {
                return ++m_Curr;
            }

            /// PostIncrement
            tIterator operator++(int)
            {
                return m_Curr++;
            }

            tIterator& operator->()
            {
                return m_Curr;
            }

            tIteratorConst& operator->() const
            {
                return m_Curr;
            }

            tElementConst& operator*() const
            {
                return *m_Curr; 
            }
            tElement operator*()
            {
                return *m_Curr; 
            }


            ::Wiz::Bool::Type IsTrue() const
            {
                return m_Curr != m_End;
            }
        protected:
            tIterator       m_Curr;
            tIteratorConst  m_End;
        };
    } // end of namespace ForEachIter

    namespace MapForEachIter
    {
        template<class ContainerT>
        struct Type : public ::Wiz::UnspecifiedBool::Type<Type<ContainerT>, ::Wiz::Noncopyable::Type>
        {
            ////////////////////////////////////
            typedef typename ContainerT::tIterator          tIterator;
            typedef typename ContainerT::tIteratorConst     tIteratorConst;

            typedef typename ContainerT::tValue             tValue;
            typedef typename ContainerT::tValueConst        tValueConst;

            typedef typename ContainerT::tIndex             tIndex;
            typedef typename ContainerT::tIndexConst        tIndexConst;
            ////////////////////////////////////

            Type(ContainerT& Container) : m_Curr(Container.Begin()), m_End(Container.End())
            {
            }

            /// PreIncrement
            tIterator operator++()
            {
                return tIterator(++m_Curr);
            }

            /// PostIncrement
            tIterator operator++(int)
            {
                return m_Curr++;
            }

            tIterator& operator->()
            {
                return m_Curr;
            }

            tIteratorConst& operator->() const
            {
                return m_Curr;
            }

            tValue& GetValue()
            {
                return m_Curr.GetValue();
            }

            tValueConst& GetValue() const
            {
                return m_Curr.GetValue();
            }

            tIndex GetIndex()
            {
                return m_Curr.GetIndex();
            }

            tIndexConst& GetIndex() const
            {
                return m_Curr.GetIndex();
            }

            ::Wiz::Bool::Type IsTrue() const
            {
                return m_Curr != m_End;
            }
        protected:
            tIterator       m_Curr;
            tIteratorConst  m_End;
        };
    } // end of namespace MapForEachIter

    //////////////////////////////////////////////////////////////////////////
    namespace ConstForEach
    {
        template<class ContainerT>
        struct Type
        {
            ////////////////////////////////////
            typedef typename ContainerT::tIteratorConst    tIterator;
            ////////////////////////////////////
            const ContainerT& m_Container;
            tIterator m_Next;
            tIterator m_End;
            tIterator& m_Curr;
            Type(tIterator& Curr, const ContainerT& Container) : m_Curr(Curr), m_Container(Container), m_Next(Container.Begin()), m_End(Container.End())
            {
            }
            ::Wiz::Bool::Type HasMoreElement()
            {
                if (m_Next != m_End)
                {
                    m_Curr = m_Next;
                    m_Next++;
                    return ::Wiz::Bool::True;
                }
                return ::Wiz::Bool::False;
            }
        };
    } /// end of namespace ConstForEach
    //////////////////////////////////////////////////////////////////////////
} /// end of namespace Wiz

#endif /*__WIZ_DATATYPE_FOREACH_HPP__SHANHAOBO_19800429__*/
